package com.leslie.hhcommunity.controller;

import com.google.code.kaptcha.Producer;
import com.leslie.hhcommunity.entity.User;
import com.leslie.hhcommunity.service.UserService;
import com.leslie.hhcommunity.util.CommunityConstant;
import com.leslie.hhcommunity.util.CommunityUtil;
import com.leslie.hhcommunity.util.RedisKeyUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author
 * @PackageName:com.leslie.hhcommunity.controller
 * @ClassnName:LoginControlleer
 * @Description:
 * @Date 2022/1/1  14:14
 */
@Controller
public class LoginController implements CommunityConstant {

	public static final Logger logger = LoggerFactory.getLogger(LoginController.class);

	@Autowired
	Producer kaptchaProducer;
	@Autowired
	UserService userService;
	@Value("server.servlet.context-path")
	private String contextPath;
	@Autowired
	RedisTemplate redisTemplate;

	@RequestMapping("/toRegister")
	public String getRegisterPath() {
		return "/site/register";
	}

	@RequestMapping("/toLogin")
	public String getLoginPath() {
		return "/site/login";
	}

	/**
	 * 注册
	 *
	 * @param model
	 * @param user
	 * @return
	 */
	@RequestMapping(value = "/register", method = RequestMethod.POST)
	public String register(Model model, User user) {
		Map<String, Object> map = userService.register(user);
		if (map == null || map.isEmpty()) {
			model.addAttribute("msg", "注册成功，我们已经向您的邮箱发送了一封激活邮件，请尽快激活！");
			//跳转到首页，等待激活
			model.addAttribute("target", "/index");
			return "site/operate-result";
		} else {
			model.addAttribute("usernameMsg", map.get("usernameMsg"));
			model.addAttribute("passwordMsg", map.get("passwordMsg"));
			model.addAttribute("emailMsg", map.get("emailMsg"));
			return "site/register";
		}
	}

	/**
	 * 处理激活
	 *
	 * @param model
	 * @param userId
	 * @param code
	 * @return
	 */
	// http://localhost:8080/community/activation/101/code
	@RequestMapping("/activation/{userId}/{code}")
	public String activation(Model model, @PathVariable("userId") int userId, @PathVariable("code") String code) {
		int result = userService.activation(userId, code);
		switch (result) {
			case ACTIVATION_SUCCESS: {
				model.addAttribute("msg", "激活成功，您的账号已经可以正常使用了！");
				model.addAttribute("target", "/toLogin");
				break;
			}
			case ACTIVATION_REPEAT: {
				model.addAttribute("msg", "无效操作，该账号已经激活过了！");
				model.addAttribute("target", "/index");
				break;
			}
			case ACTIVATION_FAILED: {
				model.addAttribute("msg", "激活失败，您提供的激活码不正确！");
				model.addAttribute("target", "/index");
				break;
			}
			default:
		}
		return "site/operate-result";
	}

	/**
	 * 生成验证码
	 *
	 * @param response
	 */
	@RequestMapping("/kaptcha")
	public void getKaptcha(HttpServletResponse response/*HttpSession session*/) {
		//生成验证码
		String text = kaptchaProducer.createText();
		BufferedImage image = kaptchaProducer.createImage(text);

		//将验证码存入session
//		session.setAttribute("kaptcha", text);

		//验证码的归属
		String kaptchaOwner = CommunityUtil.generateUUID();
		Cookie cookie = new Cookie("kaptchaOwner", kaptchaOwner);
		cookie.setMaxAge(60);
		cookie.setPath(contextPath);
		response.addCookie(cookie);
		//将验证码存入redis
		String redisKey = RedisKeyUtil.getKaptchaKey(kaptchaOwner);
		redisTemplate.opsForValue().set(redisKey, text, 60, TimeUnit.SECONDS);

		//将图片输出给浏览器
		response.setContentType("image/png");
		try {
			// 使用response输出流输出
			ServletOutputStream os = response.getOutputStream();
			ImageIO.write(image, "png", os);
		} catch (IOException e) {
			logger.error("响应验证码失败：" + e.getMessage());
		}
	}

	/**
	 * 登录
	 *
	 * @param username
	 * @param password
	 * @param code
	 * @param rememberme
	 * @param model
	 * @param kaptchaOwner
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "/login", method = RequestMethod.POST)
	public String login(String username, String password, String code, boolean rememberme,
						Model model,/*HttpSession session,*/ @CookieValue("kaptchaOwner") String kaptchaOwner, HttpServletResponse response) {
		//检验验证码
//		String kaptcha = (String) session.getAttribute("kaptcha");
		String kaptcha = null;
		if (StringUtils.isNotBlank(kaptchaOwner)) {
			String redisKey = RedisKeyUtil.getKaptchaKey(kaptchaOwner);
			kaptcha = (String) redisTemplate.opsForValue().get(redisKey);
		}
		if (StringUtils.isBlank(kaptcha) || StringUtils.isBlank(code) || !kaptcha.equals(code)) {
			model.addAttribute("codeMsg", "验证码错误");
			return "/site/login";
		}

		//检查账号，密码
		int expired = rememberme ? REMEMBER_EXPIRED_SECONDS : DEFAULT_EXPIRED_SECONDS;
		Map<String, Object> map = userService.login(username, password, expired);
		if (map.containsKey("ticket")) {
			Cookie cookie = new Cookie("ticket", map.get("ticket").toString());
			cookie.setPath(contextPath);
			cookie.setMaxAge(expired);
			response.addCookie(cookie);
			return "redirect:/index";
		} else {
			model.addAttribute("usernameMsg", map.get("usernameMsg"));
			model.addAttribute("passwordMsg", map.get("passwordMsg"));
			return "site/login";
		}
	}

	@RequestMapping("/logout")
	public String logout(@CookieValue("ticket") String ticket) {
		userService.logout(ticket);
		SecurityContextHolder.clearContext();
		return "redirect:/toLogin";
	}

}
